import axios, { AxiosPromise, AxiosRequestConfig, AxiosResponse } from "axios";
import Catch from './storage'

const defaultConfig = {
	timeout: 5000,
	baseUrl: ''
}

const axiosInstance = axios.create(defaultConfig);

interface YProps {
	[key: string]: any
}
type MethodsProps = 'GET' | 'POST' | 'PUT' | 'DELETE';
interface HeaderProps {
	headers: {
		Authorization?: string,
		[key: string]: any
	}
}

class Http {
	constructor() {
		this.httpInterceptorsRequest();
		this.httpInterceptorsResponse();
	}

	private static axiosInstance = axios.create(defaultConfig)

	// 请求拦截
	private httpInterceptorsRequest() {
		Http.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
			return config
		}, err => {
			return Promise.reject(err)
		})
	}

	// 响应拦截
	private httpInterceptorsResponse() {
		Http.axiosInstance.interceptors.response.use((response: AxiosResponse) => {
			return response
		}, err => {
			return Promise.reject(err)
		})
	}

	public httpAll<T>(url: string, data: YProps, type: MethodsProps = 'GET'): Promise<T>{

		return new Promise(function (resolve, reject) {
			// 执行异步ajax请求
			let promise: AxiosPromise<T>
			if (type.toUpperCase() === 'GET') {
				// 准备url query参数数据
				let dataStr = '' //数据拼接字符串
				Object.keys(data).forEach(key => {
					dataStr += key + '=' + data[key] + '&'
				})
				if (dataStr !== '') {
					dataStr = dataStr.substring(0, dataStr.lastIndexOf('&'))
					url = url + '?' + dataStr
				}
				// 发送get请求
				promise = axiosInstance.get(url)
			} else if (type.toUpperCase() === 'DELETE') {
				promise = axiosInstance({
					method: 'delete',
					url,
					data
				})
			} else if (type.toUpperCase() === 'PUT') {
				promise = axiosInstance.put(url, data)
			} else {
				// 发送post请求
				promise = axiosInstance.post(url, data)
			}
			promise.then(function (response: any) {
				// 成功了调用resolve()
				resolve(response.data)
			}).catch(function (error) {
				reject(error)
			})
		})
	}

	public httpAuth<T>(url: string, data: YProps, type: MethodsProps = 'GET', header: HeaderProps = {
		headers: {
			// 'Authorization': Catch.getSession('access_token') || ''
		}
	}): Promise<T>{
		return new Promise(function (resolve, reject) {
			// 执行异步ajax请求
			let promise: AxiosPromise<T>
			if (type.toUpperCase() === 'GET') {
				// 准备url query参数数据
				let dataStr = '' //数据拼接字符串
				Object.keys(data).forEach(key => {
					dataStr += key + '=' + data[key] + '&'
				})
				if (dataStr !== '') {
					dataStr = dataStr.substring(0, dataStr.lastIndexOf('&'))
					url = url + '?' + dataStr
				}
				// 发送get请求
				promise = axiosInstance.get(url, header)
			} else if (type.toUpperCase() === 'DELETE') {
				promise = axiosInstance(url, {
					method: 'delete',
					data,
					...header
				})
			} else if (type.toUpperCase() === 'PUT') {
				promise = axiosInstance.put(url, data, header)
			} else {
				// 发送post请求
				promise = axiosInstance.post(url, data, header)
			}
			promise.then(function (response: any) {
				// 成功了调用resolve()
				if (response.data.code == 401) {
					// Catch.clear(); // 清除缓存/token等
					// window.location.reload();
					// return;
				}
				resolve(response.data)
			}).catch(function (error) {
				reject(error)
			})
		})
	}

	public httpUpload<T>(url: string, data: YProps, type: MethodsProps = 'POST', header: HeaderProps = {
		headers: {
			// 'Authorization': Catch.getSession('access_token') || '',
			"Content-Type": "multipart/form-data"
		}
	}): Promise<T>{
		return new Promise(function (resolve, reject) {
			// 执行异步ajax请求
			let promise: Promise<T>
			if (type.toUpperCase() === 'GET') {
				// 准备url query参数数据
				let dataStr = '' //数据拼接字符串
				Object.keys(data).forEach(key => {
					dataStr += key + '=' + data[key] + '&'
				})
				if (dataStr !== '') {
					dataStr = dataStr.substring(0, dataStr.lastIndexOf('&'))
					url = url + '?' + dataStr
				}
				// 发送get请求
				promise = axios.get(url, header)
			} else if (type.toUpperCase() === 'PUT') {
				promise = axios.put(url, data, header)
			} else {
				promise = axios.post(url, data, header)
			}
			promise.then(function (response: any) {
				// 成功了调用resolve()
				resolve(response.data)
			}).catch(function (error) {
				reject(error)
			})
		})
	}

	public Get<T>(url: string, data: YProps): Promise<T>{
		return this.httpAuth(url, data, 'GET')
	}
	public Post<T>(url: string, data: YProps): Promise<T>{
		return this.httpAuth(url, data, 'POST')
	}
	public Put<T>(url: string, data: YProps): Promise<T>{
		return this.httpAuth(url, data, 'PUT')
	}
	public Del<T>(url: string, data: YProps = {}): Promise<T>{
		return this.httpAuth(url, data, 'DELETE')
	}
}

export const http = new Http();
export default new Http();